﻿using System;
using System.Threading;
using Common.Entities;
using Common.Enums;
using Common.Exceptions;
using Common.ServiceResponse.ValueObjects;
using Common.ServiceResponse.ValueObjects.Facebook;
using Common.Utils.Constants;
using Infrastructure.Gateways.Facebook;
using Infrastructure.Interfaces;

namespace FacebookService
{
    public class FacebookService : IFacebookService
    {
        private const string CurrentUserId = "me";
        private readonly IFacebookLoginGateway _facebookLoginGateway;
        private readonly IGatewayDetailsService _gatewayDetailsService;
        private readonly IResponseDetailsService _responseDetailsService;
        private readonly IFacebookGateway _facebookGateway;
        private readonly IConfigurationManager _configurationManager;

        public FacebookService(IFacebookLoginGateway facebookLoginGateway, IGatewayDetailsService gatewayDetailsService,
                               IResponseDetailsService responseDetailsService,IFacebookGateway facebookGateway,
                               IConfigurationManager configurationManager)
        {
            _facebookLoginGateway = facebookLoginGateway;
            _gatewayDetailsService = gatewayDetailsService;
            _responseDetailsService = responseDetailsService;
            _facebookGateway = facebookGateway;
            _configurationManager = configurationManager;
        }

        public NetworkLoginDetails LogInFacebook(SecurityKey securityKey)
        {
            var resultEvent = new AutoResetEvent(false);

            var details = _gatewayDetailsService.GetRequiredGateway(securityKey, SocialNetworkName.Facebook);
            try
            {
                _facebookLoginGateway.BuildGateway(resultEvent, details);
            }
            catch(LoginFailedException loginFailedException)
            {
                return new NetworkLoginDetails(_responseDetailsService.BuildWarningResponse(loginFailedException.Message), null);
            }
            catch(DataAccessException dataAccessException)
            {
                return new NetworkLoginDetails(_responseDetailsService.BuildWarningResponse(dataAccessException.Message), null);
            }

            if (_facebookLoginGateway.AccessToken == null)
                return new NetworkLoginDetails(_responseDetailsService.BuildWarningResponse(BusinessWarningDescription.CannotGetAccessToken), null);
            return new NetworkLoginDetails(_responseDetailsService.BuildSuccessResponse(), _facebookLoginGateway.AccessToken);
        }

        public UserProfile GetUserProfile(string accessToken)
        {
            if(!string.IsNullOrEmpty(accessToken))
            {
                /*Obtaining user profile*/
                var userProfileData = _facebookGateway.GetUserProfile(accessToken, CurrentUserId);

                /*Obtaining profile picture*/
                userProfileData.ProfilePicture = _facebookGateway.GetProfilePicture(accessToken, CurrentUserId);

                return userProfileData;
            }
            return new UserProfile(_responseDetailsService.BuildWarningResponse(BusinessWarningDescription.CannotGetUserProfile));
        }

        public Friends GetUserFriends(string accessToken, string userId)
        {
            if (!string.IsNullOrEmpty(accessToken))
            {
                var finalUserId = userId ?? CurrentUserId;
                var url = string.Format(_configurationManager.GetValue(ConfigurationKey.UserFriends), finalUserId);
                var completeFriendsUrl = string.Concat(url, accessToken);

                return GetUserFriends(completeFriendsUrl);
            }
            return new Friends(_responseDetailsService.BuildWarningResponse(BusinessWarningDescription.CannotGetUserFriends));
        }

        public Friends GetUserFriends(string pagingUrl)
        {
            if (!string.IsNullOrEmpty(pagingUrl))
            {
                var userFriends = _facebookGateway.GetUserFriends(pagingUrl);
                userFriends.ResponseDetails = _responseDetailsService.BuildSuccessResponse();

                return userFriends;
            }
            return new Friends(_responseDetailsService.BuildWarningResponse(BusinessWarningDescription.CannotGetUserFriends));
        }

        public PhotoAlbums GetPhotoAlbums(string accessToken, string userId)
        {
            if(!string.IsNullOrEmpty(accessToken))
            {
                var url = string.Format(_configurationManager.GetValue(ConfigurationKey.PhotoAlbums), userId);
                var completeAlbumsUrl = string.Concat(url, accessToken);

                return GetPhotoAlbums(completeAlbumsUrl);
            }
            return new PhotoAlbums(_responseDetailsService.BuildWarningResponse(BusinessWarningDescription.CannotGetPhotoAlbum));
        }

        public PhotoAlbums GetPhotoAlbums(string pagingUrl)
        {
            if (!string.IsNullOrEmpty(pagingUrl))
            {
                try
                {
                    var photoAlbums = _facebookGateway.GetPhotoAlbums(pagingUrl);
                    photoAlbums.ResponseDetails = _responseDetailsService.BuildSuccessResponse();
                    return photoAlbums;
                }
                catch (Exception exception)
                {
                    return new PhotoAlbums(_responseDetailsService.BuildErrorResponse(BusinessWarningDescription.CannotGetPhotoAlbum));
                }
            }
            return new PhotoAlbums(_responseDetailsService.BuildWarningResponse(BusinessWarningDescription.CannotGetPhotoAlbum));
        }

        public Photos GetPhotos(string accessToken, string albumId)
        {
            if (!string.IsNullOrEmpty(accessToken))
            {
                var url = string.Format(_configurationManager.GetValue(ConfigurationKey.Photos), albumId);
                var completePhotosUrl = string.Concat(url, accessToken);

                return GetPhotos(completePhotosUrl);
            }
            return new Photos(_responseDetailsService.BuildWarningResponse(BusinessWarningDescription.CannotGetPhotos));
        }

        public Photos GetPhotos(string pagingUrl)
        {
            if (!string.IsNullOrEmpty(pagingUrl))
            {
                try
                {
                    var photos = _facebookGateway.GetPhotos(pagingUrl);
                    photos.ResponseDetails = _responseDetailsService.BuildSuccessResponse();
                    return photos;
                }
                catch (Exception exception)
                {
                    return new Photos(_responseDetailsService.BuildErrorResponse(BusinessWarningDescription.CannotGetPhotos));
                }
            }
            return new Photos(_responseDetailsService.BuildWarningResponse(BusinessWarningDescription.CannotGetPhotos));
        }

        public Wall GetUserWall(string accessToken, string userId)
        {
            if (!string.IsNullOrEmpty(accessToken))
            {

                var finalUserId = userId ?? CurrentUserId;
                var url = string.Format(_configurationManager.GetValue(ConfigurationKey.Wall), finalUserId);
                var completeWallUrl = string.Concat(url, accessToken);

                return GetUserWall(completeWallUrl);
            }
            return new Wall(_responseDetailsService.BuildWarningResponse(BusinessWarningDescription.CannotGetPhotos));
        }

        public Wall GetUserWall(string pagingUrl)
        {
            if (!string.IsNullOrEmpty(pagingUrl))
            {
                try
                {
                    var wall = _facebookGateway.GetWall(pagingUrl);
                    wall.ResponseDetails = _responseDetailsService.BuildSuccessResponse();
                    return wall;
                }
                catch (Exception exception)
                {
                    return new Wall(_responseDetailsService.BuildErrorResponse(BusinessWarningDescription.CannotGetUserWall));
                }
            }
            return new Wall(_responseDetailsService.BuildWarningResponse(BusinessWarningDescription.CannotGetUserWall));
        }
    }
}

